#!/usr/bin/env python2
# -*- coding: utf-8 -*-

from sqlalchemy import or_

from Ump.jsonify import sqlalchemy_obj_to_dict

from Ump.common import log

from Ump.objs.db import models
from Ump.objs.session_wrapper import _sw


LOG = log.get_log('Ump.objs.db.manager')


class DBManager():

    def __init__(self):
        pass

    def oplog_create(self, params):
        username = params.pop('username', None)
        user = _sw.get_user(username)
        if user:
            params['user_id'] = user.id
            oplog = models.Oplog(params).save()
            return oplog

    def query(self, params):
        if not params:
            raise Exception(u"消息参数无效")
        return self._query_with_session(params)

    def _query_with_session(self, params):

        table = params.get('table')
        relationships = params.get('relationships')

        query = self._get_query(params)

        if table == 'disk':
            hosts = self.get_hosts()
            host_ids = [host.id for host in hosts]
            query = query.filter(models.Disk.host_id.in_(host_ids))

        if params.get('mode', '').lower() == 'all':
            order_by = params.get('order_by')
            offset = params.get('offset')
            limit = params.get('limit')

            if order_by:
                if isinstance(order_by, (tuple, list)):
                    query = query.order_by(*order_by)
                else:
                    query = query.order_by(order_by)
            if offset:
                query = query.offset(offset)
            if limit: 
                query = query.limit(limit)
            dbresult = query.all()
        elif params.get('mode', '').lower() == 'first':
            dbresult = query.first()
        elif params.get('mode', '').lower() == 'last':
            dbresult = query.all()
            if dbresult:
                dbresult = query.all()[-1]
        elif params.get('mode', '').lower() == 'count':
            dbresult = query.count()
            return dbresult 
        else:
            dbresult = query.one()
        if dbresult is None:
            return None
        
        if relationships:
            dbresult = getattr(dbresult, str(relationships))

        if isinstance(dbresult, list):
            dict_result = []
            for index, val in enumerate(dbresult):
                dict_result.append(sqlalchemy_obj_to_dict(val))
        else:
            dict_result = sqlalchemy_obj_to_dict(dbresult)

        is_print = False
        if is_print:
            LOG.info('%'*20)
            LOG.info(dbresult)
            LOG.info('%'*20)
        return dict_result

    def _get_query(self, params):
        table = params.get('table')
        model_object = models.DB_TABLE_MAP.get(table)
        if not model_object:
            raise Exception(u"请求的数据库表%s不存在"%(table))

        filter_by = params.get('filter_by', {})
        filter_ = params.get('filter', {})
        filter_not_equal = params.get('filter_not_equal', {})
        not_equal = params.get('not_equal', {})
        query = model_object.query.filter_by(deleted=False)
        username = params.get('username', None)

        user = models.User.query.filter_by(name=username).first()
        if user:
            query_contidion = self.check_anminster(user.name)
            if not query_contidion and hasattr(model_object, 'user_id'):
                query = model_object.query.filter_by(user_id=user.id)

        like_val = filter_by.pop('like1', None) 
        search_field = filter_by.pop('search_field', None)

        for key, v in not_equal.iteritems(): 
            field = getattr(model_object, key)
            query = query.filter(field != v)

        if filter_not_equal:
            for key, v in filter_not_equal.iteritems():
                field = getattr(model_object, key)
                val_list = v.split(',')
                query = query.filter(or_(field== None, ~field.in_(val_list)))
            filter_by.pop(key, None) 
            filter_.pop(key, None) 

        if filter_by: 
            query = query.filter_by(**filter_by)

        if filter_: 
            query = query.filter(**filter_)

        if like_val:
            field =  getattr(model_object, search_field)
            query = query.filter(field.like("%"+"\%s" % like_val + "%"))
        return query

    def get_hosts(self):
        hosts = models.Host.query.filter_by(deleted=False).all()
        return  hosts

    def check_anminster(self, username):
        user = models.User.query.filter_by(name=username).first()
        role = user.roles[0].name
        if role == 'administrator':
            return  True
        else:
            return  False
